using System;
using System.Collections.Generic;
using System.Linq;
using Urs.Core;
using Urs.Core.Data;
using Urs.Data.Domain.Shipping;

namespace Urs.Services.Shipping
{
    public partial class ShipmentService : IShipmentService
    {
        #region Fields

        private readonly IRepository<Shipment> _shipmentRepository;
        private readonly IRepository<ShipmentOrderItem> _sopvRepository;

        #endregion

        #region Ctor

        public ShipmentService(IRepository<Shipment> shipmentRepository,
            IRepository<ShipmentOrderItem> sopvRepository)
        {
            this._shipmentRepository = shipmentRepository;
            this._sopvRepository = sopvRepository;
        }

        #endregion

        #region Methods

        public virtual void DeleteShipment(Shipment shipment)
        {
            if (shipment == null)
                throw new ArgumentNullException("shipment");

            _shipmentRepository.Delete(shipment);

        }

        public virtual IPagedList<Shipment> GetAllShipments(string expressName, string trackingNumber, DateTime? createdFrom = null, DateTime? createdTo = null,
            int pageIndex = 0, int pageSize = int.MaxValue)
        {
            var query = _shipmentRepository.Table;
            if (createdFrom.HasValue)
                query = query.Where(s => createdFrom.Value <= s.CreateTime);
            if (createdTo.HasValue)
                query = query.Where(s => createdTo.Value >= s.CreateTime);
            if (!string.IsNullOrEmpty(expressName))
                query = query.Where(s => s.ExpressName == expressName);
            if (!string.IsNullOrEmpty(trackingNumber))
                query = query.Where(s => s.TrackingNumber == trackingNumber);

            query = query.Where(s => s.Order != null && !s.Order.Deleted);
            query = query.OrderByDescending(s => s.CreateTime);

            var shipments = new PagedList<Shipment>(query, pageIndex, pageSize);
            return shipments;
        }

        public virtual IList<Shipment> GetNotDeliverShipments(DateTime? startTime, DateTime? endTime)
        {
            var query = _shipmentRepository.Table;
            query = query.Where(s => s.ShippedTime != null && s.DeliveryTime == null);

            if (startTime.HasValue)
                query = query.Where(s => startTime.Value < s.ShippedTime);
            if (endTime.HasValue)
                query = query.Where(s => endTime.Value > s.ShippedTime);
            return query.ToList();
        }

        public virtual IList<Shipment> GetShipmentsByIds(int[] shipmentIds)
        {
            if (shipmentIds == null || shipmentIds.Length == 0)
                return new List<Shipment>();

            var query = from o in _shipmentRepository.Table
                        where shipmentIds.Contains(o.Id)
                        select o;
            var shipments = query.ToList();
            var sortedOrders = new List<Shipment>();
            foreach (int id in shipmentIds)
            {
                var shipment = shipments.Find(x => x.Id == id);
                if (shipment != null)
                    sortedOrders.Add(shipment);
            }
            return sortedOrders;
        }

        public virtual Shipment GetShipmentById(int shipmentId)
        {
            if (shipmentId == 0)
                return null;

            var shipment = _shipmentRepository.GetById(shipmentId);
            return shipment;
        }

        public virtual Shipment GetShipmentByOrderId(int orderId)
        {
            if (orderId == 0)
                return null;

            var shipment = from s in _shipmentRepository.Table
                           where s.OrderId == orderId
                           select s;
            return shipment.FirstOrDefault();
        }

        public virtual void InsertShipment(Shipment shipment)
        {
            if (shipment == null)
                throw new ArgumentNullException("shipment");

            _shipmentRepository.Insert(shipment);

        }

        public virtual void UpdateShipment(Shipment shipment)
        {
            if (shipment == null)
                throw new ArgumentNullException("shipment");

            _shipmentRepository.Update(shipment);

        }



        public virtual void DeleteShipmentOrderGoods(ShipmentOrderItem sopv)
        {
            if (sopv == null)
                throw new ArgumentNullException("sopv");

            _sopvRepository.Delete(sopv);

        }

        public virtual ShipmentOrderItem GetShipmentOrderGoodsById(int sopvId)
        {
            if (sopvId == 0)
                return null;

            var sopv = _sopvRepository.GetById(sopvId);
            return sopv;
        }

        public virtual void InsertShipmentOrderGoods(ShipmentOrderItem sopv)
        {
            if (sopv == null)
                throw new ArgumentNullException("sopv");

            _sopvRepository.Insert(sopv);

        }

        public virtual void UpdateShipmentOrderGoods(ShipmentOrderItem sopv)
        {
            if (sopv == null)
                throw new ArgumentNullException("sopv");

            _sopvRepository.Update(sopv);
        }
        #endregion
    }
}
